package com.sina.medical.core.dao;

import com.sina.medical.core.base.BaseCriteria;
import com.sina.medical.core.exception.SinaCustomException;
import org.hibernate.exception.DataException;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 这个接口是所有 Service 的基接口,这个设计的目的是避免为那些只有简单的 CRUD 操作的
 * 实体的类(如:记录访问的日志，只有保存和查询,日志是不能被更新的)写单独的 Service,
 * 同时也是对服务类的通用方法做一个抽象.
 * </p>
 *
 */
public interface BaseService {

    Serializable create(Object entity);


    void update(Object entity);

    void createOrUpdate(Object entity);

    <T> T get(Class<T> entityClass, Serializable id);

    void delete(Object entity);

    void delete(Collection entities);

    <T> boolean delete(Class<T> entityClass, Serializable id);

    <T> List<T> list(Class<T> clazz, int page, int max);

    /**
     *不支持复合 id 的实体
     */
    <T> List<T> list(Class<T> clazz, BaseCriteria criteria, long[] count);

    /**
     *
     * @throws DataException - 当 id 为 null,或 数据不存在时
     * @see #get(Class, Serializable)
     */
    <T> T getWithException(Class<T> entityClass, Serializable id)throws DataException;

    /**
     *@param entityClass (not null)
     * @param id (not null)
     * @return true 表示存在
     */
    boolean isExists(Class<?> entityClass, Serializable id);

    /**
     * 通过唯一属性查询记录是否存在
     * <p>
     * 此方法不咱们支持复合id的实体
     * </p>
     *
     * @param entityClass (not null)
     * @param propName    (not null),唯一属性的名称
     * @param uniqueProp
     * @return true 表示存在
     */
    <T> boolean isExistsByUnique(Class<T> entityClass, String propName, Serializable uniqueProp)
            throws SinaCustomException;

    /**
     * @param entityClass (not null)
     *@param id 若为 null 则无动作
     * @throws SinaCustomException - 如果存在则抛出异常
     * @see #isExists(Class, Serializable)
     */
    void isExistsWithException(Class<?> entityClass, Serializable id)throws SinaCustomException;

    default Class<?> getEntityClass(){
        return Object.class;
    }

}
